import re
import django_redis
from apps.oauth.utils import Serretoauth
from django.contrib.auth import login
from django.shortcuts import redirect,reverse, render
from django.views import View
from QQLoginTool.QQtool import OAuthQQ
from django.conf import settings
from django.http import JsonResponse,HttpResponseForbidden,HttpResponse
from apps.oauth.models import QQregister
from apps.registers.models import User
from meiduo_mall.settings.dev import logger
from utils.response_code import RETCODE
from django.contrib.auth import authenticate
# 首先需要创建一个基类模型,这个模型的字段是客户登录时间和更新时间
# 然后创建一个模型类来储存openid
# 获取token和openid并且判断openid是否绑定，如果绑定就直接重定向到首页，如果没绑定跳转到绑定页面
class QQtokenOpenidView(View):
    def get(self,request):
        # qqcode是通过查询字符发送的是一个query字典的格式.
        qqcode = request.GET.get("code")
        if not qqcode :
            return HttpResponseForbidden("ERROR:CODE不存在")
        # QQ要求发送的固定参数

        GetQqCode = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET,
                            redirect_uri=settings.QQ_REDIRECT_URI, state=1)
        try:
            # 通过code获取令牌token
            qqtoken = GetQqCode.get_access_token(qqcode)
            # 通过令牌token获取客户qq登录的唯一标识openid
            qqopenid = GetQqCode.get_open_id(qqtoken)
            # 加密
            jiami = Serretoauth()
            qqopenid = jiami.Secret(qqopenid)
        except Exception as f:
            logger.error(f)
        # 判断openid是否存在
        try :
            #从数据库中查询openid是否不存,用get查不存在会报错,所以用try判断
            openiduser = QQregister.objects.get(openid=qqopenid)
        except Exception:
            """如果不存在将网页重定向到绑定页面,而且还要把openid发送过去,
            所以这里选择用render渲染,可以传参"""
            context = {"openid":qqopenid}
            return render(request,"oauth_callback.html",context)

            # 如果存在
        else:
            """保持登录,重定向到首页,设置cookie,"""
            qq_user = openiduser.user
            login(request,qq_user)
            response = redirect(reverse("centents"))
            response.set_cookie("username",qq_user.username,max_age=24*3600*15)
            return response
        # 绑定openid
    def post(self,request):
        """
        1.验证表单信息:判空,判正则,判是否值相等
        2.判断表单中的手机号是否存在,存在的话直接绑定,不存在创建一个存到数据库然后绑定
        3.保持登录,重定向,设置cookie
        """
        mobile = request.POST.get("mobile")
        password = request.POST.get("password")
        sms_code = request.POST.get("sms_code")
        openid = request.POST.get("openid")
        # 加密
        jiemi = Serretoauth()
        openid = jiemi.Unsecret(openid)
        # # 1.验证表单信息: 判空, 判正则, 判是否值相等
        # if not all([mobile,password,sms_code]):
        #     return HttpResponseForbidden("请完成填写表单")
        # if not re.match("^1[345789]\d{9}$",mobile):
        #     return HttpResponseForbidden("手机格式不正确")
        # if not re.match("^[0-9a-zA-Z-_]{8,20}$",password):
        #     return HttpResponseForbidden("密码格式不正确")
        # # 链接redis数据库获取验证码，判断
        # redis_ob = django_redis.get_redis_connection("sys_code")
        # redis_code = redis_ob.get(mobile)
        # if redis_code is None :
        #     return render(request, 'oauth_callback.html', {'sms_code_errmsg': '短信验证码不存在'})
        # if redis_code.decode() != sms_code:
        #     return render(request, 'oauth_callback.html', {'sms_code_errmsg': '输入短信验证码有误'})
        # 2.判断表单中的手机号是否存在, 存在的话直接绑定, 不存在创建一个存到数据库然后绑定.
        # 判断下openid是否过期
        if not openid :
            return render(request, 'oauth_callback.html', {'openid_errmsg': '无效的openid'})
        # 绑定QQ时如果绑定的手机号不存在，直接注册手机号。
        if not User.objects.filter(mobile=mobile):
            user = User.objects.create_user(username=mobile,password=password,mobile=mobile)
        else:
        # 如果手机号存在，检查手机号密码是否正确。
            user = authenticate(username=mobile,password=password)
        # 2.1绑定openid
        QQregister.objects.create(openid=openid,user=user)
        # 3.保持登录,重定向,设置cookie
        login(request,user)
        response = redirect(reverse("centents"))
        response.set_cookie("username",user,max_age=24*3600*14)
        return response
"""
当我们客户通过我们发送的QQ登录网址登录后QQ会把网页重定向到我们
在QQ开发者中注册应用上预留的网页,我们需要一个接口来处理这里的逻辑
且,QQ会把code给我们,获取code
"""
# 获取qq登录的url让客户登录qq
class QQoauth(View):
    def get(self,request):
        """
        用QQLoginTool实现QQ的第三方登录,登录方法可以说只有四个步骤
        1.通过 appid和appkey获取QQ的code
        2.通过QQ返回的这个code得到token令牌
        3.通过token令牌获取对应唯一的openid
        4.将openid和我们的用户实现绑定
        """
        # 创建QAuthQQ对象，传入必传参数
        GetQqCode = OAuthQQ(client_id=settings.QQ_CLIENT_ID,client_secret=settings.QQ_CLIENT_SECRET,
                            redirect_uri=settings.QQ_REDIRECT_URI,state=1)
        # 获取QQ登录的url
        SendQqurl = GetQqCode.get_qq_url()
        # 返回给前端json格式
        return JsonResponse({
            "code":RETCODE.OK,
            "errmsg":"ok",
            "login_url":SendQqurl
        })